package sentinel.demo.test;

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.csp.sentinel.util.TimeUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class FlowThreadDemo {

    private static AtomicInteger pass               = new AtomicInteger();
    private static AtomicInteger    block              = new AtomicInteger();
    private static AtomicInteger    total              = new AtomicInteger();
    private static AtomicInteger    activeThread       = new AtomicInteger();

    private static volatile boolean stop               = false;

    // 60s时间后, methodB业务处理耗时为20ms, 那每个线程访问资源时最低耗时就变成了20ms, 处理速度加快
    private static final int        threadCount        = 100;

    private static int              seconds            = 60 + 40;

    // methodB模拟调用别人的服务, 业务耗时1s, 配置线程数阈值为20, 同样的线程数, methodB业务耗时降级, 则这20个线程能处理的请求能力上升, 能接受更多的请求
    private static volatile int     methodBRunningTime = 1000;

    public static void main(String[] args) throws Exception {
        System.out.println("MethodA will call methodB. After running for a while, methodB becomes fast, "
                           + "which make methodA also become fast ");
        initFlowRule();

        for (int i = 0; i < threadCount; i++) {
            Thread entryThread = new Thread(() -> {
                    Entry methodA = null;
                    try {
                        System.out.println(Thread.currentThread().getName()+"=============");
                        methodA = SphU.entry("methodA");
                    } catch (BlockException e1) {
                        block.incrementAndGet();
                    } catch (Exception e2) {
                        // biz exception
                    } finally {
                        total.incrementAndGet();
                        if (methodA != null) {
                            methodA.exit();
                            activeThread.decrementAndGet();
                        }
                    }
            });
            entryThread.start();
        }
    }

    private static void initFlowRule() {
        List<FlowRule> rules = new ArrayList<FlowRule>();
        FlowRule rule1 = new FlowRule();
        rule1.setResource("methodA");
        // set limit concurrent thread for 'methodA' to 20
        // 设置该资源的线程数阈值为20个
        rule1.setCount(5);
        // 基于并发线程数限流
        rule1.setGrade(RuleConstant.FLOW_GRADE_THREAD);
        rule1.setLimitApp("default");

        rules.add(rule1);
        FlowRuleManager.loadRules(rules);
    }


}
